package Controleur;
import Vue.DamierVue;
import Vue.FinPartieVue;
import Modele.Damier;
import Modele.GestionMouvement;
import Modele.Joueur;
import Vue.AProposVue;

/**
 * Classe permettant de gérer les mouvements
 * @author El Meknassi Hamza (10806466) - Migeon Cyril (11007322)
 */
public class ControlePartie {

    //Damier utilisé pour la partie
    private Damier damier;

    //Vues utilisées
    private AProposVue aProposVue;
    private DamierVue damVue;
    private FinPartieVue finVue = null;

    //Permet de gérer les déplacements
    private GestionMouvement gestionMvt;

    //Différents joueurs
    private Joueur J1;
    private Joueur J2;

    //Variable permettant de savoir si le prochain clic permettra de faire appel à la fonction déplacer ou pas
    private int deplacerOk = 0;

    //Coordonnées de la case source lors d'un appel à la fonction déplacer, leur valeur est modifiée après un premier clic
    private int xSrc=-1;
    private int ySrc=-1;

    //Int permettant d'identifier le joueur actif
    private int joueurActif = 0;
    
    /**
     * Constructeur de ControlePartie
     */
    public ControlePartie(){}

    /**
     * Création d'une nouvelle partie
     */
    public void nouvellePartie()
    {
        damier = new Damier();
        damier.placerPieces();
        gestionMvt = new GestionMouvement(damier);
        J1 = new Joueur('b',"Joueur 1");
        J2 = new Joueur('n',"Joueur 2");
        damVue = new DamierVue(J1.getNom(), J2.getNom(), this);
        damVue.setVisible(true);

        //la vue observe le modèle, en particulier la classe qui effectue les déplacements
        gestionMvt.addObserver(damVue);
        
        J1.setPeutJouer(true);
        damVue.panneauActif(1);
        gestionMvt.nouveauTour(J1);
        damVue.colorierCases();
    }

     /**
     * Gère l'ensemble des actions (clics) : déplacements, prises ...
     * @param cx
     * @param cy
     */
    public void gererClic(int cx, int cy)
    {
        System.out.println("Mouse clicked >> ["+cx+","+cy+"]");
        Joueur joueur = null;

        //S'il s'agit du premier clic, on sauvegarde la position de la case sélectionnée
        if (deplacerOk == 0)
        {
            //On vérifie que la case est occupée par une pièce
            if (damier.getEtatCase(cx, cy)==1)
            {
                //On identifie à quel joueur appartient la pièce
                if(damier.getCouleurPiece(cx, cy) == 'b')   { joueurActif = 1; joueur = J1; }
                else    { joueurActif = 2; joueur = J2; }

                //On vérifie si le joueur peut jouer
                if (joueur.getPeutJouer())
                {
                    //On met la variable deplacerOk à 1 pour qu'au prochain clic on effectue un déplacement
                    deplacerOk = 1;

                    //On met un fond jaune pour la case sélectionnée
                    damVue.selectionnerCase(correspondance(cx, cy));

                    //Ce sera la case de départ pour le déplacement
                    xSrc=cx;
                    ySrc=cy;
                }
                else
                    System.out.println("Ce n'est pas votre tour !");
            }
        }

        //Si deplacerOk est à 1, cela veut dire qu'il s'agit d'un clic sur une case cible,
        //on essaye donc de faire un déplacement
        else if(deplacerOk == 1)
        {
            //Variable permettant de savoir s'il s'agit d'un déplacement, prise ou prise multiple
            int tailleMeilleurCoup =gestionMvt.getDeplacementMax();

            //On identifie le joueur actif
            if (joueurActif == 1) joueur = J1;
            else if (joueurActif ==2) joueur = J2;
            
            if (gestionMvt.deplacement(joueur, damier.getCase(xSrc, ySrc), damier.getCase(cx, cy)))
            {
                //On teste si la partie est terminee
                testFinPartie();

                //On définit à qui est le prochain tour
                definirProchainTour(tailleMeilleurCoup);

                //On efface les anciennes cases proposées
                damVue.viderCasesProposees();

                //On colorie les cases pouvant effectuer un déplacement pour que le joueur puisse les voir
                if (gestionMvt.getDeplacementMax() > 0)
                    damVue.casesProposees(gestionMvt.getPositionCasesJouables());
            }
            else
                System.out.println("Déplacement non autorisé !");
            
            damVue.deselectionnerCase(correspondance(xSrc, ySrc));

            //Permet de laisser la case cible sélectionnée si le joueur peut faire une prise multiple
            if (tailleMeilleurCoup -2 < 0)
                deplacerOk = 0;
            else
            {
                damVue.selectionnerCase(correspondance(cx, cy));
                xSrc = cx;
                ySrc = cy;
                deplacerOk = 1;
            }
        }
    }

    /**
     * Permet de définir à qui sera le tour (joueur adverse si déplacement ou prise simple, même joueur si prise multiple)
     * @param tailleMeilleurCoup
     */
    private void definirProchainTour(int tailleMeilleurCoup)
    {
        if (joueurActif == 1)
        {
            // Si la taille du meilleur est inférieure à 2 (on peut faire au mieux une prise simple) alors au prochain tour,
            // c'est le joueur adverse qui joue
            if (tailleMeilleurCoup  < 2)
            {
                J1.setPeutJouer(false);
                J2.setPeutJouer(true);
                damVue.panneauActif(2);
                gestionMvt.nouveauTour(J2);
            }

            // La taille du meilleur coup est supérieure à 2, le joueur peut faire une prise multiple, on lui laisse la main
            else
                gestionMvt.nouveauTour(J1);
        }
        // Même chose quand c'est le joueur 2 qui joue
        else
        {
            if (tailleMeilleurCoup < 2)
            {
                J1.setPeutJouer(true);
                J2.setPeutJouer(false);
                damVue.panneauActif(1);
                gestionMvt.nouveauTour(J1);
           }
            else
                gestionMvt.nouveauTour(J2);
        }
    }


    private void testFinPartie()
    {
        boolean fin = false;
        String nomJoueur = "";
        if (damier.getNbPiecesBlanches() == 0)
        {
            fin = true;
            nomJoueur= J2.getNom();
        }
        else if (damier.getNbPiecesNoires() == 0)
        {
            fin = true;
            nomJoueur= J1.getNom();
        }
        if (fin)
        {
            damVue.disable();
            finVue = new FinPartieVue(nomJoueur, this);
            finVue.setLocationRelativeTo(damVue);
            finVue.setVisible(true);
        }
    }

    /**
     * Permet de lancer une nouvelle partie et de fermer l'ancienne
     */
    public void rejouer()
    {
        damVue.dispose();
        if (finVue != null)
            finVue.dispose();
        this.nouvellePartie();
    }


    /**
     * Permet d'obtenir l'état de la case donnée en paramètre
     * @param x
     * @param y
     * @return l'état de la case
     */
    public int getEtatCase (int x, int y)
    {
        return damier.getEtatCase(x, y);
    }

    /**
     * Permet d'obtenir la couleur de la pièce présente sur la case donnée en paramètre (ses coordonnées)
     * @param x
     * @param y
     * @return couleur de la pièce
     */
    public char getCouleurCase(int x, int y)
    {
        return damier.getCouleurPiece(x, y);
    }

    /**
     * Demande au modele s'il y a une dame sur les coordonnées données en paramètre
     * @param x
     * @param y
     * @return vrai si dame, faux sinon
     */
    public boolean isDame(int x, int y)
    {
        boolean booleen = false;
        if (damier.isDame(x,y))
            booleen = true;
        
        return booleen;
    }

    /**
     * Fonction permettant d'identifier les différentes cases en fonction de leurs coordonnées
     * @param a
     * @param b
     * @return id - L'identifiant de la case de coordonnées (a,b)
     */
    private int correspondance(int a, int b)
    {
        int id = 0;
        int tabId[][] = new int [10][10];
        for (int y=0; y<10; y++)
        {
            for (int x=0; x< 10; x++)
            {
                tabId[x][y]=id;
                id++;
            }
        }
        return tabId[a][b];
    }


    /**
     * Ouvre la boite de dialogque A Propos De
     */
    public void aPropos()
    {
        aProposVue = new AProposVue(damVue, true, this);
        aProposVue.setLocationRelativeTo(damVue);
        aProposVue.setVisible(true);
    }

    /**
     * Ferme la boite de dialogue A propos de
     */
    public void fermerAPropos()
    {
        aProposVue.dispose();
    }


}